package smokesignals.data.db4o;

import com.db4o.Db4oEmbedded;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;
import com.googlecode.recycled.data.AbstractDataStore;
import com.googlecode.recycled.data.WithId;

/**
 * @author Henryk Konsek
 */
public class Db4oDataStore<T> extends AbstractDataStore<T> {

    protected ObjectContainer container;

    public Db4oDataStore(String containerPath) {
        container = Db4oEmbedded.openFile(containerPath);

        registerQuerySupport(Predicate.class, new PredicateQueryHandler(container));
    }

    @Override
    protected void doStore(WithId<T> withId) {
        container.store(withId);
    }

    @Override
    protected void doDelete(WithId<T> withId) {
        container.delete(withId);
    }

    @Override
    protected <V extends WithId<T>> V doLoad(Class<V> clazz, final T id) {
        ObjectSet<V> results = container.query(new Predicate<V>() {
            @Override
            public boolean match(V t) {
                return t.getId().equals(id);
            }
        });
        if (results.isEmpty()) {
            return null;
        } else if (results.size() == 1) {
            return results.get(0);
        } else {
            throw new IllegalArgumentException(String.format("Too many results returned (%s) for value %s .", results.size(), id));
        }
    }

    @Override
    public void close() {
        container.close();
    }

}
